"""
任务数据模型
"""

from typing import Dict, Any, Optional, List
from datetime import datetime, timedelta
from .base import BaseModel


class Task(BaseModel):
    """任务模型类"""
    
    # 任务状态常量
    STATUS_PENDING = 'pending'
    STATUS_PROCESSING = 'processing'
    STATUS_COMPLETED = 'completed'
    STATUS_FAILED = 'failed'
    STATUS_CANCELLED = 'cancelled'
    
    # 支持的输出格式
    SUPPORTED_FORMATS = {
        'docx', 'pdf', 'html', 'epub', 'odt', 'rtf', 'tex', 'pptx'
    }
    
    def __init__(self):
        super().__init__('tasks')
    
    def create_task(self, task_data: Dict[str, Any]) -> str:
        """
        创建新任务
        
        Args:
            task_data: 任务数据
            
        Returns:
            str: 任务ID
        """
        # 生成任务ID
        task_id = self.generate_id()
        
        # 构建任务记录
        task_record = {
            'task_id': task_id,
            'filename': task_data.get('filename'),
            'original_filename': task_data.get('original_filename'),
            'file_path': task_data.get('file_path'),
            'file_size': task_data.get('file_size', 0),
            'output_format': task_data.get('output_format', 'docx'),
            'options': task_data.get('options', {}),
            'status': self.STATUS_PENDING,
            'progress': 0,
            'current_step': '等待处理',
            'user_id': task_data.get('user_id'),
            'celery_task_id': task_data.get('celery_task_id'),
            'output_path': None,
            'download_url': None,
            'quality_score': None,
            'error_message': None,
            'retry_count': 0,
            'estimated_duration': self._estimate_duration(task_data),
            'metadata': task_data.get('metadata', {})
        }
        
        # 验证输出格式
        if task_record['output_format'] not in self.SUPPORTED_FORMATS:
            raise ValueError(f"不支持的输出格式: {task_record['output_format']}")
        
        # 创建记录
        self.create(task_record)
        return task_id
    
    def get_task(self, task_id: str) -> Optional[Dict[str, Any]]:
        """
        获取任务信息
        
        Args:
            task_id: 任务ID
            
        Returns:
            Optional[Dict]: 任务信息或None
        """
        return self.find_one({'task_id': task_id})
    
    def update_task_status(self, task_id: str, status: str, 
                          error_message: str = None) -> bool:
        """
        更新任务状态
        
        Args:
            task_id: 任务ID
            status: 新状态
            error_message: 错误信息（可选）
            
        Returns:
            bool: 是否更新成功
        """
        update_data = {
            'status': status,
            'updated_at': self.get_current_time()
        }
        
        if error_message:
            update_data['error_message'] = error_message
        
        # 如果任务完成或失败，记录完成时间
        if status in [self.STATUS_COMPLETED, self.STATUS_FAILED, self.STATUS_CANCELLED]:
            update_data['completed_at'] = self.get_current_time()
        
        return self.update_one({'task_id': task_id}, update_data)
    
    def update_task_progress(self, task_id: str, progress: int, 
                           status: str = None, current_step: str = None) -> bool:
        """
        更新任务进度
        
        Args:
            task_id: 任务ID
            progress: 进度百分比 (0-100)
            status: 任务状态（可选）
            current_step: 当前步骤描述（可选）
            
        Returns:
            bool: 是否更新成功
        """
        update_data = {
            'progress': max(0, min(100, progress)),
            'updated_at': self.get_current_time()
        }
        
        if status:
            update_data['status'] = status
        
        if current_step:
            update_data['current_step'] = current_step
        
        return self.update_one({'task_id': task_id}, update_data)
    
    def complete_task(self, task_id: str, output_path: str, 
                     quality_score: int = None, download_url: str = None) -> bool:
        """
        完成任务
        
        Args:
            task_id: 任务ID
            output_path: 输出文件路径
            quality_score: 质量评分
            download_url: 下载URL
            
        Returns:
            bool: 是否更新成功
        """
        update_data = {
            'status': self.STATUS_COMPLETED,
            'progress': 100,
            'current_step': '转换完成',
            'output_path': output_path,
            'completed_at': self.get_current_time()
        }
        
        if quality_score is not None:
            update_data['quality_score'] = quality_score
        
        if download_url:
            update_data['download_url'] = download_url
        
        return self.update_one({'task_id': task_id}, update_data)
    
    def fail_task(self, task_id: str, error_message: str) -> bool:
        """
        标记任务失败
        
        Args:
            task_id: 任务ID
            error_message: 错误信息
            
        Returns:
            bool: 是否更新成功
        """
        # 增加重试次数
        task = self.get_task(task_id)
        retry_count = task.get('retry_count', 0) + 1 if task else 1
        
        update_data = {
            'status': self.STATUS_FAILED,
            'error_message': error_message,
            'retry_count': retry_count,
            'completed_at': self.get_current_time()
        }
        
        return self.update_one({'task_id': task_id}, update_data)
    
    def get_user_tasks(self, user_id: str, status: str = None, 
                      limit: int = 50, skip: int = 0) -> List[Dict[str, Any]]:
        """
        获取用户任务列表
        
        Args:
            user_id: 用户ID
            status: 任务状态过滤（可选）
            limit: 限制数量
            skip: 跳过数量
            
        Returns:
            List[Dict]: 任务列表
        """
        query = {'user_id': user_id}
        
        if status:
            query['status'] = status
        
        return self.find_many(
            query=query,
            sort=[('created_at', -1)],
            limit=limit,
            skip=skip
        )
    
    def get_active_tasks(self, limit: int = 100) -> List[Dict[str, Any]]:
        """
        获取活跃任务列表
        
        Args:
            limit: 限制数量
            
        Returns:
            List[Dict]: 活跃任务列表
        """
        query = {
            'status': {'$in': [self.STATUS_PENDING, self.STATUS_PROCESSING]}
        }
        
        return self.find_many(
            query=query,
            sort=[('created_at', 1)],
            limit=limit
        )
    
    def get_completed_tasks(self, hours_ago: int = 24) -> List[Dict[str, Any]]:
        """
        获取已完成的任务
        
        Args:
            hours_ago: 多少小时前完成的任务
            
        Returns:
            List[Dict]: 已完成任务列表
        """
        cutoff_time = self.get_current_time() - timedelta(hours=hours_ago)
        
        query = {
            'status': {'$in': [self.STATUS_COMPLETED, self.STATUS_FAILED]},
            'completed_at': {'$lt': cutoff_time}
        }
        
        return self.find_many(query=query)
    
    def cleanup_completed_tasks(self, hours_ago: int = 24) -> int:
        """
        清理已完成的任务记录
        
        Args:
            hours_ago: 多少小时前完成的任务
            
        Returns:
            int: 清理的任务数量
        """
        cutoff_time = self.get_current_time() - timedelta(hours=hours_ago)
        
        query = {
            'status': {'$in': [self.STATUS_COMPLETED, self.STATUS_FAILED]},
            'completed_at': {'$lt': cutoff_time}
        }
        
        return self.delete_many(query)
    
    def get_task_statistics(self, user_id: str = None) -> Dict[str, Any]:
        """
        获取任务统计信息
        
        Args:
            user_id: 用户ID（可选，为空则统计所有用户）
            
        Returns:
            Dict: 统计信息
        """
        base_query = {}
        if user_id:
            base_query['user_id'] = user_id
        
        # 统计各状态任务数量
        stats = {
            'total': self.count(base_query),
            'pending': self.count({**base_query, 'status': self.STATUS_PENDING}),
            'processing': self.count({**base_query, 'status': self.STATUS_PROCESSING}),
            'completed': self.count({**base_query, 'status': self.STATUS_COMPLETED}),
            'failed': self.count({**base_query, 'status': self.STATUS_FAILED}),
            'cancelled': self.count({**base_query, 'status': self.STATUS_CANCELLED})
        }
        
        # 计算成功率
        if stats['total'] > 0:
            stats['success_rate'] = round(
                (stats['completed'] / stats['total']) * 100, 2
            )
        else:
            stats['success_rate'] = 0
        
        return stats
    
    def _estimate_duration(self, task_data: Dict[str, Any]) -> int:
        """
        估算任务执行时间（秒）
        
        Args:
            task_data: 任务数据
            
        Returns:
            int: 估算时间（秒）
        """
        base_time = 30  # 基础时间30秒
        
        # 根据文件大小调整
        file_size = task_data.get('file_size', 0)
        if file_size > 1024 * 1024:  # 大于1MB
            base_time += (file_size // (1024 * 1024)) * 10
        
        # 根据输出格式调整
        output_format = task_data.get('output_format', 'docx')
        format_multipliers = {
            'pdf': 2.0,
            'epub': 1.5,
            'docx': 1.0,
            'html': 0.8,
            'odt': 1.2,
            'rtf': 0.9,
            'tex': 1.3,
            'pptx': 1.8
        }
        
        multiplier = format_multipliers.get(output_format, 1.0)
        
        return int(base_time * multiplier)